<?php

/**
 * 安心站长axzz.cn，一个追求技术创造者。让网站、小程序、APP牛起来……
 *
 * cighsen02 365182575
 *
 * Create at: 2025.08.28
 * Update at: 2025.09.15
 */

namespace Twoir\Service;

use Config;
use Exception;
use Twoir\Controller\Info;
use Twoir\Controller\Member;
use Twoir\Controller\OffiAccount;

use function camel_case;
use function forward_static_call_array;
use function in_array;
use function str_contains;

/**
 * Http核心
 */
class HttpKernel
{
    const USER_URL = ['logout', 'login', 'register', 'set_fava', 'show_key'];

    private static $instance;

    protected array $post;
    protected array $get;

    private bool $isJson = true;

    private $response;

    private ?string $action = null;

    private ?string $method = null;
    // 来源url
    private ?string $origin_url = null;

    private function __construct(
        protected array $options
    )
    {
        $this->post = $_POST;
        $this->get  = $_GET;
        $this->action = $_POST['act'] ?? $_GET['act'] ?? null;
        $this->origin_url = $_SERVER['HTTP_ORIGIN'] ?? $_SERVER['HTTP_REFERER'] ?? $_SERVER['REMOTE_ADDR'] ?? null;

        $this->init();
    }

    /**
     * Summary of init
     * 
     * @return void
     */
    protected function init()
    {
        if ($this->action && in_array($this->action, static::USER_URL)) {

            $this->method = str_contains($this->action, '_') ? camel_case($this->action) : $this->action;
            $this->action = 'user';
        }
        // // 公众号
        // elseif ($this->action && in_array($this->action, ['access_token'])) {

        // 	$method = str_contains($this->action, '_') ? camel_case($this->action) : $this->action;
        // 	$this->action = 'offi';
        // }
        // 公众号
        elseif(null === $this->action && (isset($this->get['signature']) || isset($this->get['echostr']))) {

            $this->method = 'verify';
            $this->action = 'offi';
        }
        // 调用信息时简化参数 不传act参数
        elseif (null === $this->action && (isset($this->get['classid']) || isset($this->get['tablename']))) {

            $this->action = 'info';
        }

        // 响应格式
        $this->isJson = match(true) {
            $this->method && $this->method === 'verify' => false,
            $this->action && in_array($this->action, ['generate', 'qrcode'], true) => false,
            default => true
        };
    }

    /**
     * 禁止克隆
     */
    private function __clone()
    {}

    /**
     * 获取唯一实例
     * 
     * @param array|null $options
     * @return static
     */
    public static function getInstance(?array $options = null)
    {
        if (!(static::$instance instanceof static)) {

            $options ??= Config::twoir('api');

            static::$instance = new static($options);
        }

        return static::$instance;
    }

    /**
     * Summary of withoutUser
     * 
     * @return bool
     */
    public function withMember(): bool
    {
        return $this->action && in_array($this->action, ['query', 'download']);
    }

    /**
     * 获取工作方式，后面删除
     * 
     * @return bool
     */
    public function isApiEnabled(): bool
    {
        return $this->isJson;
    }

    /**
     * Summary of handle
     * 
     * @return void
     */
    public function handle()
    {
        $this->response = match($this->action) {
            // 获取信息
            'info' => Info::get($this->get),
            // 点击
            'click' => Info::onClick($this->get),
            // 会员
            'user' => forward_static_call_array([Member::class, $this->method], [in_array($this->method, ['logout', 'setFava', 'showKey'], true) ? $this->get : $this->post]),
            // 公众号
            'offi' => forward_static_call_array([OffiAccount::class, $this->method], [$this->get, $this->post]),
            // 非法请求
            default => throw new Exception('非法请求', 9401)
        };
    }

    /**
     * 向客户端响应
     * 
     * @return void
     */
    public function response()
    {
        // json格式输出
        if ($this->isJson) {

            $this->jsonResponse();
        }
        // 二维码输出
        elseif (is_object($this->response) && method_exists($this->response, 'render')) {

            header('Content-Type: ' . $this->response->getContentType() . ';charset=utf-8');

            echo $this->response->render($this->get['qrurl'] ?? '');
        }
        // 定义标准输出
        else {

            header('content-type: text/html;charset=utf-8');

            echo $this->response;
        }
    }

    /**
     * 向客户端json响应
     * 
     * @return void
     */
    public function jsonResponse(): void
    {
        $result = [
            'code' => 0,
            'message' => 'Ok'
        ];

        if ($this->response) $result['data'] = $this->response;

        header('Content-type: application/json;charset=utf-8');

        echo json_encode($result, 15);
    }
}
